import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import tkinter.font as tkFont  # 新增导入，用于设置字体
import mysql.connector
from mysql.connector import Error
from shibie2 import recognize_invoice, save_to_database
from PIL import Image, ImageTk

# 数据库连接信息
DB_CONFIG = {
    'host': 'localhost',
    'port': 3306,
    'user': 'root',
    'password': '123456',
    'database': 'fapiao'
}

# 添加全局变量
edit_mode = False
selected_item = None
selected_column = None
entry = None
edit_button = None
edit_mode_label = None

# 新增检索相关全局变量
search_mode = False
search_buttons_frame = None
search_type = None
search_button = None
exit_search_button = None
search_mode_label = None

# 映射中文名称和数据库列名
COLUMN_MAPPING = {
    "客户名称": "purchaser_name",
    "发票名称": "invoice_name",
    "开票日期": "issue_date"
}


# 初始化 MySQL 数据库表
def init_db():
    try:
        connection = mysql.connector.connect(**DB_CONFIG)
        cursor = connection.cursor()
        create_table_query = """
        CREATE TABLE IF NOT EXISTS fapiao (
            id INT AUTO_INCREMENT PRIMARY KEY,
            invoice_image_url TEXT,
            invoice_name TEXT,
            invoice_code TEXT,
            invoice_number TEXT,
            issue_date DATE,
            purchaser_name TEXT,
            seller_name TEXT,
            goods_name TEXT,
            specification_model TEXT,
            unit TEXT,
            quantity FLOAT,
            amount FLOAT,
            tax_rate FLOAT,
            tax_amount FLOAT,
            total_amount FLOAT,
            total_tax_amount FLOAT,
            total_price_tax FLOAT
        )
        """
        cursor.execute(create_table_query)
        connection.commit()
    except Error as e:
        print(f"初始化数据库表时出现错误: {e}")
    finally:
        if connection.is_connected():
            cursor.close()
            connection.close()

def upload_invoice():
    file_path = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg;*.png")])
    if file_path:
        try:
            result = recognize_invoice(file_path)
            if result:
                save_to_database(result, file_path)
                messagebox.showinfo("提示", "上传成功")
                refresh_invoice_list()
            else:
                messagebox.showerror("错误", f"发票识别失败，图片路径: {file_path}")
        except Exception as e:
            messagebox.showerror("错误", f"上传失败: {e}")

# 刷新发票列表
def refresh_invoice_list():
    try:
        connection = mysql.connector.connect(**DB_CONFIG)
        cursor = connection.cursor()
        select_query = "SELECT id, invoice_name, invoice_number, invoice_code, issue_date, purchaser_name, goods_name, total_amount, invoice_image_url FROM fapiao"
        cursor.execute(select_query)
        rows = cursor.fetchall()
        for item in tree.get_children():
            tree.delete(item)
        num = 1
        invoice_num = 1
        prev_invoice_number = None
        for row in rows:
            current_invoice_number = row[2]
            if prev_invoice_number is not None and current_invoice_number != prev_invoice_number:
                invoice_num += 1
            prev_invoice_number = current_invoice_number
            # 将数据库中的 id 作为第一个值添加，其他值依次往后排
            new_row = (row[0], num, invoice_num, row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8])
            tree.insert("", "end", values=new_row)
            num += 1
    except Error as e:
        print(f"刷新发票列表时出现错误: {e}")
    finally:
        if connection.is_connected():
            cursor.close()
            connection.close()


# 按照发票名称和日期检索
def search_invoices():
    name_keyword = name_search_entry.get()
    date_keyword = date_search_entry.get()
    try:
        connection = mysql.connector.connect(**DB_CONFIG)
        cursor = connection.cursor()
        query = "SELECT id, invoice_name, invoice_number, invoice_code, issue_date, purchaser_name, goods_name, total_amount, invoice_image_url FROM fapiao WHERE 1=1"
        if name_keyword:
            query += f" AND invoice_name LIKE '%{name_keyword}%'"
        if date_keyword:
            query += f" AND issue_date LIKE '%{date_keyword}%'"
        cursor.execute(query)
        rows = cursor.fetchall()
        for item in tree.get_children():
            tree.delete(item)
        num = 1
        invoice_num = 1
        prev_invoice_number = None
        for row in rows:
            current_invoice_number = row[2]
            if prev_invoice_number is not None and current_invoice_number != prev_invoice_number:
                invoice_num += 1
            prev_invoice_number = current_invoice_number
            # 将数据库中的 id 作为第一个值添加，其他值依次往后排
            new_row = (row[0], num, invoice_num, row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8])
            tree.insert("", "end", values=new_row)
            num += 1
    except Error as e:
        print(f"搜索发票时出现错误: {e}")
    finally:
        if connection.is_connected():
            cursor.close()
            connection.close()

# 按照日期范围和文字统计
def statistics():
    start_date = start_date_stat_entry.get()
    end_date = end_date_stat_entry.get()
    keyword = keyword_stat_entry.get()
    try:
        connection = mysql.connector.connect(**DB_CONFIG)
        cursor = connection.cursor()
        query = "SELECT COUNT(DISTINCT invoice_number), SUM(total_amount) FROM (SELECT invoice_number, MAX(total_amount) as total_amount FROM fapiao WHERE 1=1"
        if start_date and end_date:
            query += f" AND issue_date BETWEEN '{start_date}' AND '{end_date}'"
        if keyword:
            query += f" AND (invoice_name LIKE '%{keyword}%' OR goods_name LIKE '%{keyword}%')"
        query += " GROUP BY invoice_number) subquery"
        cursor.execute(query)
        result = cursor.fetchone()
        count = result[0]
        total_amount = result[1]
        messagebox.showinfo("统计结果", f"总张数: {count}, 总金额: {total_amount}")
    except Error as e:
        print(f"统计发票时出现错误: {e}")
    finally:
        if connection.is_connected():
            cursor.close()
            connection.close()

# 退出登录
def logout():
    root.destroy()
    show_login_window()

def show_image(event):
    selected_item = tree.selection()
    if selected_item:
        item = tree.item(selected_item)
        values = item['values']
        image_url = values[-1]
        # 获取屏幕宽度和高度
        screen_width = root.winfo_screenwidth()
        screen_height = root.winfo_screenheight()

        # 创建新窗口
        info_window = tk.Toplevel(root)
        info_window.title("发票信息")
        window_width = 400  # 适当缩小窗口宽度
        window_height = 200  # 适当缩小窗口高度
        # 计算窗口的 x 和 y 坐标以实现居中
        x = (screen_width - window_width) // 2
        y = (screen_height - window_height) // 2
        info_window.geometry(f"{window_width}x{window_height}+{x}+{y}")

        def open_image():
            try:
                img = Image.open(image_url)
                img = img.resize((800, 600))
                photo = ImageTk.PhotoImage(img)
                image_window = tk.Toplevel(root)
                image_window.title("发票图片")
                label = tk.Label(image_window, image=photo)
                label.image = photo
                label.pack()
            except Exception as e:
                messagebox.showerror("错误", f"无法打开图片: {e}")

        def show_detail_info():
            detail_window = tk.Toplevel(root)
            detail_window.title("发票详细信息")
            window_width = 400  # 适当缩小详细信息窗口宽度
            window_height = 300  # 适当缩小详细信息窗口高度
            # 计算详细信息窗口的 x 和 y 坐标以实现居中
            x = (screen_width - window_width) // 2
            y = (screen_height - window_height) // 2
            detail_window.geometry(f"{window_width}x{window_height}+{x}+{y}")

            # 创建一个 Canvas 组件
            canvas = tk.Canvas(detail_window)
            canvas.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

            # 创建垂直滚动条
            scrollbar = tk.Scrollbar(detail_window, command=canvas.yview)
            scrollbar.pack(side=tk.RIGHT, fill=tk.Y)

            # 配置 Canvas 与滚动条关联
            canvas.configure(yscrollcommand=scrollbar.set)

            # 创建一个框架用于放置详细信息标签
            frame = tk.Frame(canvas)
            canvas.create_window((0, 0), window=frame, anchor=tk.NW)

            columns = ["发票名称", "发票代码", "发票号码", "开票日期", "客户名称", "销售方名称", "商品名称", "规格型号", "单位", "数量", "金额", "税率", "税额", "总金额", "总税额", "价税合计"]
            db_columns = ["invoice_name", "invoice_code", "invoice_number", "issue_date", "purchaser_name", "seller_name", "goods_name", "specification_model", "unit", "quantity", "amount", "tax_rate", "tax_amount", "total_amount", "total_tax_amount", "total_price_tax"]
            invoice_id = values[0]  # 获取当前选中发票的 id
            try:
                connection = mysql.connector.connect(**DB_CONFIG)
                cursor = connection.cursor()
                for col, db_col in zip(columns, db_columns):
                    query = f"SELECT {db_col} FROM fapiao WHERE id = %s"
                    cursor.execute(query, (invoice_id,))
                    result = cursor.fetchone()
                    value = result[0] if result else ""
                    label = tk.Label(frame, text=f"{col}: {value}")
                    label.pack(pady=2)

                # 更新 Canvas 的滚动区域
                frame.update_idletasks()
                canvas.config(scrollregion=canvas.bbox(tk.ALL))
            except Error as e:
                print(f"获取详细信息时出现错误: {e}")
                messagebox.showerror("错误", f"获取详细信息时出现错误: {e}")
            finally:
                if connection.is_connected():
                    cursor.close()
                    connection.close()

        button_frame = tk.Frame(info_window)  # 创建一个框架用于放置按钮
        button_frame.pack(pady=50)  # 使用 pady 调整框架位置，让按钮更居中

        image_button = tk.Button(button_frame, text="图片", command=open_image)
        image_button.pack(side=tk.LEFT, padx=10)

        detail_button = tk.Button(button_frame, text="详细信息", command=show_detail_info)
        detail_button.pack(side=tk.LEFT, padx=10)

# 删除选中的发票信息
def delete_invoice():
    selected_item = tree.selection()
    if selected_item:
        item = tree.item(selected_item)
        values = item['values']
        # 现在数据库中的 id 是 values 列表的第一个元素
        invoice_id = values[0]
        confirm = messagebox.askyesno("确认删除", "确定要删除这条发票信息吗？")
        if confirm:
            try:
                connection = mysql.connector.connect(**DB_CONFIG)
                cursor = connection.cursor()
                delete_query = "DELETE FROM fapiao WHERE id = %s"
                cursor.execute(delete_query, (invoice_id,))
                connection.commit()
                messagebox.showinfo("提示", "删除成功")
                refresh_invoice_list()
            except Error as e:
                messagebox.showerror("错误", f"删除失败: {e}")
            finally:
                if connection.is_connected():
                    cursor.close()
                    connection.close()


# 显示主窗口
def show_main_window():
    global root, tree, name_search_entry, date_search_entry, start_date_stat_entry, end_date_stat_entry, keyword_stat_entry, search_window, statistics_window, edit_mode, edit_button, edit_mode_label
    global search_mode, search_buttons_frame, search_type, search_button, exit_search_button, search_mode_label
    root = tk.Tk()
    root.title("发票管理系统")

    # 设置窗口大小，宽度保持 800，高度为原来的三分之二
    window_width = 800
    window_height = int(600 * 2 / 3)

    # 获取屏幕宽度和高度
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()

    # 计算窗口的 x 和 y 坐标以实现居中
    x = (screen_width - window_width) // 2
    y = (screen_height - window_height) // 2

    # 设置窗口的位置和大小
    root.geometry(f"{window_width}x{window_height}+{x}+{y}")

    # 顶部按钮栏
    button_frame = tk.Frame(root)
    button_frame.pack(side=tk.TOP, fill=tk.X)

    user_button = tk.Button(button_frame, text="用户", command=lambda: show_logout_option())
    user_button.pack(side=tk.LEFT, padx=5)

    upload_button = tk.Button(button_frame, text="上传", command=upload_invoice)
    upload_button.pack(side=tk.LEFT, padx=5)

    # 修改检索按钮
    global search_button
    search_button = tk.Button(button_frame, text="检索", command=start_search)
    search_button.pack(side=tk.LEFT, padx=5)
    search_button.bind("<Enter>", show_search_sub_buttons)
    search_button.bind("<Leave>", hide_search_sub_buttons)
    statistics_button = tk.Button(button_frame, text="统计", command=show_statistics_selection_window)
    statistics_button.pack(side=tk.LEFT, padx=5)

    delete_button = tk.Button(button_frame, text="删除", command=delete_invoice)
    delete_button.pack(side=tk.LEFT, padx=5)

    # 初始时只显示修改按钮
    edit_button = tk.Button(button_frame, text="修改", command=start_edit)
    edit_button.pack(side=tk.LEFT, padx=5)

    # 添加修改模式提示标签，初始隐藏
    edit_mode_label = tk.Label(root, text="修改模式", fg="red")
    edit_mode_label.pack(anchor=tk.NE, padx=10, pady=10)
    edit_mode_label.pack_forget()

    # 添加检索模式提示标签，初始隐藏
    search_mode_label = tk.Label(root, text="检索模式", fg="blue")
    search_mode_label.pack(anchor=tk.SE, padx=10, pady=10)
    search_mode_label.pack_forget()

    # 搜索窗口
    search_window = tk.Toplevel(root)
    search_window.withdraw()
    name_search_label = tk.Label(search_window, text="发票名称:")
    name_search_label.pack(side=tk.LEFT, padx=5)
    name_search_entry = tk.Entry(search_window)
    name_search_entry.pack(side=tk.LEFT, padx=5)
    date_search_label = tk.Label(search_window, text="发票日期:")
    date_search_label.pack(side=tk.LEFT, padx=5)
    date_search_entry = tk.Entry(search_window)
    date_search_entry.pack(side=tk.LEFT, padx=5)
    search_submit_button = tk.Button(search_window, text="搜索", command=search_invoices)
    search_submit_button.pack(side=tk.LEFT, padx=5)

    # 统计窗口
    statistics_window = tk.Toplevel(root)
    statistics_window.withdraw()
    start_date_stat_label = tk.Label(statistics_window, text="开始日期:")
    start_date_stat_label.pack(side=tk.LEFT, padx=5)
    start_date_stat_entry = tk.Entry(statistics_window)
    start_date_stat_entry.pack(side=tk.LEFT, padx=5)
    end_date_stat_label = tk.Label(statistics_window, text="结束日期:")
    end_date_stat_label.pack(side=tk.LEFT, padx=5)
    end_date_stat_entry = tk.Entry(statistics_window)
    end_date_stat_entry.pack(side=tk.LEFT, padx=5)
    keyword_stat_label = tk.Label(statistics_window, text="关键词:")
    keyword_stat_label.pack(side=tk.LEFT, padx=5)
    keyword_stat_entry = tk.Entry(statistics_window)
    keyword_stat_entry.pack(side=tk.LEFT, padx=5)
    statistics_submit_button = tk.Button(statistics_window, text="统计", command=statistics)
    statistics_submit_button.pack(side=tk.LEFT, padx=5)

    # 发票列表表格
    frame = tk.Frame(root)
    frame.pack(fill=tk.BOTH, expand=True)

    tree = ttk.Treeview(frame, columns=("id", "编号", "发票编号", "发票名称", "发票号码", "发票代码", "开票日期", "客户名称", "商品名称", "总金额", "图片路径"), show="headings")
    tree.heading("id", text="")  # 隐藏 id 列的标题
    tree.column("id", width=0, stretch=tk.NO)  # 隐藏 id 列
    tree.heading("编号", text="编号")
    tree.column("编号", width=50)  # 缩小“编号”列宽度
    tree.heading("发票编号", text="发票编号")
    tree.column("发票编号", width=80)  # 缩小“发票编号”列宽度
    tree.heading("发票名称", text="发票名称")
    tree.heading("发票号码", text="发票号码")
    tree.heading("发票代码", text="发票代码")
    tree.heading("开票日期", text="开票日期")
    tree.heading("客户名称", text="客户名称")
    tree.heading("商品名称", text="商品名称")
    tree.heading("总金额", text="总金额")
    tree.heading("图片路径", text="图片路径")
    tree.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
    tree.bind("<Double-1>", show_image)

    # 水平滚动条
    scrollbar = ttk.Scrollbar(frame, orient="horizontal", command=tree.xview)
    scrollbar.pack(side=tk.BOTTOM, fill=tk.X)
    tree.configure(xscrollcommand=scrollbar.set)

    # 初始化数据库
    init_db()
    refresh_invoice_list()

    # 运行主循环
    root.mainloop()

# 显示统计选择窗口
def show_statistics_selection_window():
    statistics_selection_window = tk.Toplevel(root)
    statistics_selection_window.title("选择统计类型")

    # 设置窗口大小
    window_width = 300
    window_height = 200

    # 获取屏幕宽度和高度
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()

    # 计算窗口的 x 和 y 坐标以实现居中
    x = (screen_width - window_width) // 2
    y = (screen_height - window_height) // 2

    # 设置窗口的位置和大小
    statistics_selection_window.geometry(f"{window_width}x{window_height}+{x}+{y}")

    # 定义统计类型选项，添加“统计所有发票”
    types = ["客户名称", "发票名称", "开票日期", "统计所有发票"]
    selected_type = tk.StringVar(statistics_selection_window)
    selected_type.set(types[0])  # 默认选择第一个选项

    # 创建 OptionMenu 组件
    option_menu = tk.OptionMenu(statistics_selection_window, selected_type, *types)
    option_menu.pack(pady=20)

    def on_statistics_select():
        selected = selected_type.get()
        statistics_selection_window.destroy()
        perform_statistics(selected)

    # 创建确认按钮
    confirm_button = tk.Button(statistics_selection_window, text="确认", command=on_statistics_select)
    confirm_button.pack(pady=20)

# 执行统计操作
def perform_statistics(type):
    if type == "开票日期":
        # 创建一个新的窗口用于输入开票日期
        date_window = tk.Toplevel(root)
        date_window.title("输入开票日期")

        # 年输入框
        year_label = tk.Label(date_window, text="年:")
        year_label.pack(side=tk.LEFT, padx=5)
        year_entry = tk.Entry(date_window)
        year_entry.pack(side=tk.LEFT, padx=5)

        # 月输入框
        month_label = tk.Label(date_window, text="月:")
        month_label.pack(side=tk.LEFT, padx=5)
        month_entry = tk.Entry(date_window)
        month_entry.pack(side=tk.LEFT, padx=5)

        # 日输入框
        day_label = tk.Label(date_window, text="日:")
        day_label.pack(side=tk.LEFT, padx=5)
        day_entry = tk.Entry(date_window)
        day_entry.pack(side=tk.LEFT, padx=5)

        def on_date_confirm():
            year = year_entry.get().zfill(4) if year_entry.get() else '%'
            month = month_entry.get().zfill(2) if month_entry.get() else '%'
            day = day_entry.get().zfill(2) if day_entry.get() else '%'
            keyword = f"{year}-{month}-{day}"
            date_window.destroy()
            actual_column = COLUMN_MAPPING.get(type)
            if actual_column:
                try:
                    connection = mysql.connector.connect(**DB_CONFIG)
                    cursor = connection.cursor()
                    query = f"SELECT COUNT(DISTINCT invoice_number), SUM(total_amount) FROM (SELECT invoice_number, MAX(total_amount) as total_amount FROM fapiao WHERE {actual_column} LIKE '{keyword}' GROUP BY invoice_number) subquery"
                    cursor.execute(query)
                    result = cursor.fetchone()
                    count = result[0]
                    total_amount = result[1]
                    messagebox.showinfo("统计结果", f"总张数: {count}, 总金额: {total_amount}")
                except Error as e:
                    print(f"统计发票时出现错误: {e}")
                    messagebox.showerror("错误", f"统计发票时出现错误: {e}")
                finally:
                    if connection.is_connected():
                        cursor.close()
                        connection.close()

        # 确认按钮
        confirm_button = tk.Button(date_window, text="确认", command=on_date_confirm)
        confirm_button.pack(pady=10)
    elif type == "统计所有发票":
        try:
            connection = mysql.connector.connect(**DB_CONFIG)
            cursor = connection.cursor()
            query = "SELECT COUNT(DISTINCT invoice_number), SUM(total_amount) FROM (SELECT invoice_number, MAX(total_amount) as total_amount FROM fapiao GROUP BY invoice_number) subquery"
            cursor.execute(query)
            result = cursor.fetchone()
            count = result[0]
            total_amount = result[1]
            messagebox.showinfo("统计结果", f"总张数: {count}, 总金额: {total_amount}")
        except Error as e:
            print(f"统计所有发票时出现错误: {e}")
            messagebox.showerror("错误", f"统计所有发票时出现错误: {e}")
        finally:
            if connection.is_connected():
                cursor.close()
                connection.close()
    else:
        keyword = tk.simpledialog.askstring("输入统计关键词", f"请输入 {type} 的统计关键词")
        if keyword:
            actual_column = COLUMN_MAPPING.get(type)
            if actual_column:
                try:
                    connection = mysql.connector.connect(**DB_CONFIG)
                    cursor = connection.cursor()
                    query = f"SELECT COUNT(DISTINCT invoice_number), SUM(total_amount) FROM (SELECT invoice_number, MAX(total_amount) as total_amount FROM fapiao WHERE {actual_column} LIKE '%{keyword}%' GROUP BY invoice_number) subquery"
                    cursor.execute(query)
                    result = cursor.fetchone()
                    count = result[0]
                    total_amount = result[1]
                    messagebox.showinfo("统计结果", f"总张数: {count}, 总金额: {total_amount}")
                except Error as e:
                    print(f"统计发票时出现错误: {e}")
                    messagebox.showerror("错误", f"统计发票时出现错误: {e}")
                finally:
                    if connection.is_connected():
                        cursor.close()
                        connection.close()

# 开始检索
def start_search():
    global search_mode, search_button, exit_search_button, search_mode_label
    search_mode = True
    search_button.pack_forget()
    exit_search_button = tk.Button(search_button.master, text="退出检索", command=lambda: end_search())
    exit_search_button.pack(side=tk.LEFT, padx=5)
    search_mode_label.pack(anchor=tk.SE, padx=10, pady=10)

    # 创建一个新的顶层窗口用于选择检索类型
    search_type_window = tk.Toplevel(root)
    search_type_window.title("选择检索类型")

    # 设置窗口大小
    window_width = 300
    window_height = 200

    # 获取屏幕宽度和高度
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()

    # 计算窗口的 x 和 y 坐标以实现居中
    x = (screen_width - window_width) // 2
    y = (screen_height - window_height) // 2

    # 设置窗口的位置和大小
    search_type_window.geometry(f"{window_width}x{window_height}+{x}+{y}")

    # 定义检索类型选项
    types = ["客户名称", "发票名称", "开票日期"]
    selected_type = tk.StringVar(search_type_window)
    selected_type.set(types[0])  # 默认选择第一个选项

    # 创建 OptionMenu 组件
    option_menu = tk.OptionMenu(search_type_window, selected_type, *types)
    option_menu.pack(pady=20)

    def on_select():
        selected = selected_type.get()
        search_type_window.destroy()
        perform_search(selected)

    # 创建确认按钮
    confirm_button = tk.Button(search_type_window, text="确认", command=on_select)
    confirm_button.pack(pady=20)

# 结束检索
def end_search():
    global search_mode, search_button, exit_search_button, search_mode_label
    search_mode = False
    exit_search_button.pack_forget()
    search_button.pack(side=tk.LEFT, padx=5)
    search_mode_label.pack_forget()
    refresh_invoice_list()  # 恢复显示所有数据
    

# 鼠标移入检索按钮时显示子按钮
def show_search_sub_buttons(event):
    global search_buttons_frame
    if not search_mode:
        search_buttons_frame = tk.Frame(search_button.master)
        search_buttons_frame.place(x=search_button.winfo_x(), y=search_button.winfo_y() + search_button.winfo_height())
        customer_name_button = tk.Button(search_buttons_frame, text="客户名称", command=lambda: start_search("purchaser_name"))
        customer_name_button.pack(side=tk.LEFT, padx=5)
        invoice_name_button = tk.Button(search_buttons_frame, text="发票名称", command=lambda: start_search("invoice_name"))
        invoice_name_button.pack(side=tk.LEFT, padx=5)
        issue_date_button = tk.Button(search_buttons_frame, text="开票日期", command=lambda: start_search("issue_date"))
        issue_date_button.pack(side=tk.LEFT, padx=5)

# 鼠标移出检索按钮时隐藏子按钮
def hide_search_sub_buttons(event):
    global search_buttons_frame
    if search_buttons_frame:
        search_buttons_frame.destroy()

# 执行检索操作
def perform_search(type):
    if type == "开票日期":
        # 创建一个新的窗口用于输入开票日期
        date_window = tk.Toplevel(root)
        date_window.title("输入开票日期")

        # 年输入框
        year_label = tk.Label(date_window, text="年:")
        year_label.pack(side=tk.LEFT, padx=5)
        year_entry = tk.Entry(date_window)
        year_entry.pack(side=tk.LEFT, padx=5)

        # 月输入框
        month_label = tk.Label(date_window, text="月:")
        month_label.pack(side=tk.LEFT, padx=5)
        month_entry = tk.Entry(date_window)
        month_entry.pack(side=tk.LEFT, padx=5)

        # 日输入框
        day_label = tk.Label(date_window, text="日:")
        day_label.pack(side=tk.LEFT, padx=5)
        day_entry = tk.Entry(date_window)
        day_entry.pack(side=tk.LEFT, padx=5)

        def on_date_confirm():
            year = year_entry.get().zfill(4) if year_entry.get() else '%'
            month = month_entry.get().zfill(2) if month_entry.get() else '%'
            day = day_entry.get().zfill(2) if day_entry.get() else '%'
            keyword = f"{year}-{month}-{day}"
            date_window.destroy()
            actual_column = COLUMN_MAPPING.get(type)
            if actual_column:
                try:
                    connection = mysql.connector.connect(**DB_CONFIG)
                    cursor = connection.cursor()
                    query = f"SELECT id, invoice_name, invoice_number, invoice_code, issue_date, purchaser_name, goods_name, total_amount, invoice_image_url FROM fapiao WHERE {actual_column} LIKE '{keyword}'"
                    print("执行的查询语句:", query)  # 添加调试信息输出
                    cursor.execute(query)
                    rows = cursor.fetchall()
                    for item in tree.get_children():
                        tree.delete(item)
                    num = 1
                    invoice_num = 1
                    prev_invoice_number = None
                    for row in rows:
                        current_invoice_number = row[2]
                        if prev_invoice_number is not None and current_invoice_number != prev_invoice_number:
                            invoice_num += 1
                        prev_invoice_number = current_invoice_number
                        new_row = (row[0], num, invoice_num, row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8])
                        tree.insert("", "end", values=new_row)
                        num += 1
                except Error as e:
                    print(f"搜索发票时出现错误: {e}")
                    messagebox.showerror("错误", f"搜索发票时出现错误: {e}")
                finally:
                    if connection.is_connected():
                        cursor.close()
                        connection.close()

        # 确认按钮
        confirm_button = tk.Button(date_window, text="确认", command=on_date_confirm)
        confirm_button.pack(pady=10)
    else:
        keyword = tk.simpledialog.askstring("输入检索关键词", f"请输入 {type} 的检索关键词")
        if keyword:
            actual_column = COLUMN_MAPPING.get(type)
            if actual_column:
                try:
                    connection = mysql.connector.connect(**DB_CONFIG)
                    cursor = connection.cursor()
                    query = f"SELECT id, invoice_name, invoice_number, invoice_code, issue_date, purchaser_name, goods_name, total_amount, invoice_image_url FROM fapiao WHERE {actual_column} LIKE '%{keyword}%'"
                    print("执行的查询语句:", query)  # 添加调试信息输出
                    cursor.execute(query)
                    rows = cursor.fetchall()
                    for item in tree.get_children():
                        tree.delete(item)
                    num = 1
                    invoice_num = 1
                    prev_invoice_number = None
                    for row in rows:
                        current_invoice_number = row[2]
                        if prev_invoice_number is not None and current_invoice_number != prev_invoice_number:
                            invoice_num += 1
                        prev_invoice_number = current_invoice_number
                        new_row = (row[0], num, invoice_num, row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8])
                        tree.insert("", "end", values=new_row)
                        num += 1
                except Error as e:
                    print(f"搜索发票时出现错误: {e}")
                    messagebox.showerror("错误", f"搜索发票时出现错误: {e}")
                finally:
                    if connection.is_connected():
                        cursor.close()
                        connection.close()

# 开启修改模式
def start_edit():
    global edit_mode, edit_button, edit_mode_label
    edit_mode = True
    tree.bind("<Double-1>", on_double_click)
    edit_button.config(text="退出修改", command=stop_edit)
    edit_mode_label.pack(anchor=tk.NE, padx=10, pady=10)

# 退出修改模式
def stop_edit():
    global edit_mode, edit_button, edit_mode_label
    if 'entry' in globals() and entry.winfo_exists():
        answer = messagebox.askyesno("保存修改", "是否保存修改内容？")
        if answer:
            save_edit()
    edit_mode = False
    tree.unbind("<Double-1>")
    tree.bind("<Double-1>", show_image)
    edit_button.config(text="修改", command=start_edit)
    edit_mode_label.pack_forget()
    # 移除可能存在的编辑框
    if 'entry' in globals():
        entry.destroy()

# 双击单元格编辑
def on_double_click(event):
    if not edit_mode:
        show_image(event)
        return
    global entry, selected_item, selected_column
    item = tree.identify_row(event.y)
    column = tree.identify_column(event.x)
    if item and column:
        selected_item = item
        selected_column = int(column[1:]) - 1  # 转换为索引
        x, y, width, height = tree.bbox(item, column)
        value = tree.set(item, column)
        entry = tk.Entry(tree)
        entry.place(x=x, y=y, width=width, height=height)
        entry.insert(0, value)
        entry.focus()
        entry.bind("<Return>", lambda e: save_edit())
        entry.bind("<Escape>", lambda e: cancel_edit())

# 保存编辑内容
def save_edit():
    global entry, selected_item, selected_column
    new_value = entry.get()
    values = list(tree.item(selected_item, 'values'))
    values[selected_column] = new_value
    tree.item(selected_item, values=values)
    invoice_id = values[0]
    column_name = tree['columns'][selected_column]
    # 映射界面显示名和数据库列名
    column_mapping = {
        "发票名称": "invoice_name",
        # 这里可以补充其他界面显示名和数据库列名的映射关系
    }
    actual_column_name = column_mapping.get(column_name, column_name)
    if actual_column_name != 'id':
        try:
            connection = mysql.connector.connect(**DB_CONFIG)
            cursor = connection.cursor()
            # 构建更新语句
            if actual_column_name == '编号' or actual_column_name == '发票编号':
                return  # 编号和发票编号不允许修改
            update_query = f"UPDATE fapiao SET {actual_column_name} = %s WHERE id = %s"
            cursor.execute(update_query, (new_value, invoice_id))
            connection.commit()
        except Error as e:
            messagebox.showerror("错误", f"更新数据库失败: {e}")
        finally:
            if connection.is_connected():
                cursor.close()
                connection.close()
    entry.destroy()

# 取消编辑
def cancel_edit():
    global entry
    entry.destroy()


# 显示退出选项
def show_logout_option():
    logout_window = tk.Toplevel(root)
    logout_button = tk.Button(logout_window, text="退出", command=logout)
    logout_button.pack(pady=20)

# 显示搜索窗口
def show_search_window():
    search_window.deiconify()


# 登录验证函数
def login_verify():
    username = username_entry.get()
    password = password_entry.get()
    if username == "root" and password == "123456":
        login_window.destroy()
        show_main_window()
    else:
        messagebox.showerror("登录失败", "用户名或密码错误")

# 显示登录窗口
def show_login_window():
    global login_window, username_entry, password_entry
    login_window = tk.Tk()
    login_window.title("登录")
    login_window.geometry("800x450")

    # 添加标题标签
    title_font = tkFont.Font(family="Helvetica", size=20, weight="bold")
    title_label = tk.Label(login_window, text="发票管理系统", font=title_font)
    title_label.pack(pady=20)  # 使用 pady 调整与下方组件的间距

    username_label = tk.Label(login_window, text="用户名:")
    username_label.pack(pady=10)
    username_entry = tk.Entry(login_window)
    username_entry.pack(pady=5)

    password_label = tk.Label(login_window, text="密码:")
    password_label.pack(pady=10)
    password_entry = tk.Entry(login_window, show='*')
    password_entry.pack(pady=5)

    login_button = tk.Button(login_window, text="登录", command=login_verify)
    login_button.pack(pady=20)

    login_window.mainloop()
if __name__ == "__main__":
    show_login_window()